package com.github.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

public class AESEncrypt {
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    private static final String DEFAULT_VALUE = "0";
    private static final String KEY_ALGORITHM = "AES";
    private static final int SECRET_KEY_LENGTH = 32;
    private static final Charset UTF8 = StandardCharsets.UTF_8;

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static String encrypt(String str) {
        try {
            String secretKey = getSecretKey();
            String substring = secretKey.substring(0, 16);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(1, getSecretKey(secretKey), new IvParameterSpec(substring.getBytes(UTF8)));
            return Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes(UTF8)));
        } catch (Exception e) {
            return "error";
        }
    }

    public static String decrypt(String str) {
        try {
            String secretKey = getSecretKey();
            String substring = secretKey.substring(0, 16);
            byte[] base64Decode = Base64.getDecoder().decode(str);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(2, getSecretKey(secretKey), new IvParameterSpec(substring.getBytes(StandardCharsets.UTF_8)));
            return new String(cipher.doFinal(base64Decode), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
    }

    private static String getSecretKey() {
        return Utils.encrypt();
    }

    public static SecretKeySpec getSecretKey(String str) {
        return new SecretKeySpec(toMakeKey(str).getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
    }

    private static String toMakeKey(String str) {
        int length = str.length();
        if (length >= AESEncrypt.SECRET_KEY_LENGTH) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(str);
        for (int i2 = 0; i2 < AESEncrypt.SECRET_KEY_LENGTH - length; i2++) {
            sb.append(AESEncrypt.DEFAULT_VALUE);
        }
        return sb.toString();
    }
}
